<?php
class TBB_Model_Users extends Zend_Db_Table_Abstract
{	
	const NOT_FOUND = 1;
	const WRONG_PW = 2;
	
	/**
	 * Username of user
	 * @var string
	 */
	protected $_name = 'users';
	
	/**
	 * Primary column of user table
	 * @var unknown_type
	 */
	protected $_primary = 'user_id';

	/**
	 * Create user helper
	 * @param string $username
	 * @param string $password
	 * @param int $customerID
	 * @return int
	 */
	protected function _createUser($username, $password, $customerID = null)
	{
		$userRow = $this->createRow();
		if($userRow) {
			if(!$this->userExists($username)) {
				$userRow->customer_id = $customerID;	
				$userRow->username = $username;	
				$userRow->salt = md5($this->createSalt());
				$userRow->password = sha1($password . $userRow->salt);
				
				$dateFormat = new Zend_Date();
				$now = $dateFormat->toString('yy-MM-dd hh:mm:ss');
				$userRow->last_visit_date = $now;
				
				// get user ID
				return $userRow->save();
			}			
			throw new Exception('Could not create user. This user existed!');						
		}
		throw new Exception('Could not create user. Users not found.');	
	}
	
	/**
	 * Create roles for user
	 * @param array $roleIDs
	 */
	protected function _createRolesForUser($userID, $roleIDs = array())
	{
		$db = Zend_Db_Table::getDefaultAdapter();
		foreach($roleIDs as $roleID) {
			$db->insert('user2role', array('user_id' => $userID, 'role_id' => $roleID));					
		}	
	}
	
	/**
	 * Authenticate the user logged in
	 * @param string $username
	 * @param string $password
	 * @return stdClass
	 */
	public function authenticate($username, $password)
	{
		$select = $this->select()->from('users')->where('username = ?', array($username));
		$user = $this->fetchRow($select);		
		if($user) {
			$passwordFromDB = $user->password;
			$password = sha1($password . $user->salt);
			if($password == $passwordFromDB) {	
				$obj = new stdClass();
				$obj->username = $username;			
				return $obj;
			}
			throw new Exception(self::WRONG_PW);
		}
		throw new Exception(self::NOT_FOUND);
	}
	
	/**
	 * Check if the user is admin
	 * @param int $userID
	 * @return bool
	 */
	public function isAdminUser($userID)
	{
		$roles = $this->getRolesOfUser($userID);
		foreach($roles as $role) {
			if($role['role_name'] == 'admin') {
				return true;
			}
		}
		return false;
	}
		
	/**
	 * Add roles to user array
	 * @param array $userArray $userArray has form Array([0] => Array([user_id] => 1, [customer_id] => 3, ...),
	 * 													 [1] => Array([user_id] => 2, [customer_id] => 4, ...),
	 * 													 ...)
	 * @return array modified userArray
	 */
	public function addRolesToUserArray($userArray)
	{
		foreach($userArray as $index => $user)
		{
			$userID = $user['user_id'];
			$roleArray = $this->getRolesOfUser($userID);
			$userArray[$index]['roles'] = $roleArray;
		}
		return $userArray;	
	}

	/**
	 * Get roles of specified user
	 * @param int $userID
	 * @return array
	 */
	public function getRolesOfUser($userID)
	{
		$db = Zend_Db_Table::getDefaultAdapter();
		$stmt = $db->query('CALL list_roles_of_user(?)', $userID);
		$roleArray = $stmt->fetchAll();
		return $roleArray;
	}

	
	/**
	 * Get user array
	 * @return array
	 */
	public function getUserArray()
	{
		$select = $this->select();
		$select->order(array('username'));
		return $this->fetchAll($select)->toArray();
	}	
	
	/**
	 * Check if the user exists
	 * @param  $username
	 * @return bool
	 */
	public function userExists($username)
	{
		$select = $this->select()->where('username = ?', $username);				
		$user = $this->fetchRow($select);
		return $user ? true : false;	
	}
	
	/**
	 * Update user
	 * @param $id
	 * @param $userName
	 * @param $password
	 * @param $isPasswordChanged
	 * @return int
	 */
	public function updateUser($id, $userName, $password, $isPasswordChanged = false)
	{
		$userRow = $this->find($id)->current();
		if($userRow) {
			$userRow->username = $userName;
			if($isPasswordChanged) {
				$userRow->password = sha1($password . $userRow->salt);
			}
			$userRow->save();
			return $userRow;
		} else {
			throw new Zend_Exception('Could not update user. Users not found.');
		}
	}
	
	/**
	 * Delete user
	 * @param int $id
	 * @return int
	 */
	public function deleteUser($id)
	{
		$userRow = $this->find($id)->current();
		if($userRow) {
			$userRow->delete();
		} else {
			throw new Zend_Exception('Could not delete user. Users not found.');
		}
	}
    
	/**
	 * Return user ID by username
	 * @param $username
	 * @return int
	 */
	public function getUserIDByUsername($username)
	{
		$select = $this->select()->from('users', array('user_id'))->where('username = ?', $username);
		$r = $this->fetchRow($select);
		if($r != null) {
			$a = $r->toArray();
			return $a['user_id'];			
		}		
		return null;
	}

	/**
	 * Return salt by username
	 * @param int $userID
	 * @return string
	 */
	public function getSaltByUsername($username)
	{
		$select = $this->select()->from('users', array('salt'))->where('username = ?', $username);
		$r = $this->fetchRow($select);
		if($r != null) {
			$a = $r->toArray();
			return $a['salt'];			
		}
		return null;
	}	
	
	/**
	 * Return salt by user ID
	 * @param int $userID
	 * @return string
	 */
	public function getSaltByUserID($userID)
	{		
		$select = $this->select()->from('users', array('salt'))->where('user_id = ?', $userID);		
		$r = $this->fetchRow($select);
		if($r != null) {
			$a = $r->toArray();
			return $a['salt'];
		}
		return null;
	}
	
	/**
	 * Create salt (helper)
	 * @return string
	 */
    private function createSalt()
    {
        $salt = '';
        for ($i = 0; $i < 50; $i++) {
            $salt .= chr(rand(33, 126));
        }
        return $salt;
    }
}